package com.java.util;

import com.java.util.pojo.IntrospectionUser;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

public class MapToBeanReflection {

    public static void main(String[] args) {
        Map<String, Object> userMap = new HashMap<>();
        userMap.put("name", "张三");
        userMap.put("age", 25); // 注意这里是字符串，但我们的转换方法会处理
        userMap.put("email", "zhangsan@example.com");
        userMap.put("extraField", "这个字段会被忽略"); // User类中没有这个字段

        // 使用反射方法转换
        IntrospectionUser user = MapToBeanReflection.toBean(IntrospectionUser.class, userMap);

        System.out.println(user); // 输出: User{name='张三', age=25, email='zhangsan@example.com'}
    }


    public static <T> T toBean(Class<T> clazz, Map<String, Object> map) {
        try {
            // 创建目标类的实例
            T obj = clazz.getDeclaredConstructor().newInstance();

            // 获取所有声明的字段（包括私有字段）
            Field[] fields = clazz.getDeclaredFields();

            for (Field field : fields) {
                String fieldName = field.getName();

                // 检查Map中是否包含该字段名
                if (map.containsKey(fieldName)) {
                    Object value = map.get(fieldName);

                    // 如果值为null或空字符串，则跳过
                    if (value == null || "".equals(value)) {
                        continue;
                    }
                    // 如果Map中的值类型与字段类型不匹配，尝试类型转换
                    if (!field.getType().isInstance(value)) {
                        value = convertType(value, field.getType());
                    }

                    // 构建setter方法名（遵循JavaBean规范）
                    String setterName = "set" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);

                    try {
                        // 获取setter方法
                        Method setter = clazz.getMethod(setterName, field.getType());



                        // 调用setter方法设置值
                        setter.invoke(obj, value);
                    } catch (NoSuchMethodException e) {
                        // 如果没有找到setter方法，尝试直接设置字段值
                        try {
                            field.setAccessible(true); // 允许访问私有字段
                            field.set(obj, value);
                        } catch (IllegalAccessException ex) {
                            System.err.println("无法设置字段 " + fieldName + ": " + ex.getMessage());
                        }
                    }
                }
            }

            return obj;
        } catch (Exception e) {
            throw new RuntimeException("转换Map到对象失败", e);
        }
    }

    /**
     * 简单的类型转换方法
     * 实际应用中可能需要更复杂的类型转换逻辑
     */
    private static Object convertType(Object value, Class<?> targetType) {
        if (value == null) {
            return null;
        }

        // 如果已经是目标类型，直接返回
        if (targetType.isInstance(value)) {
            return value;
        }

        // 处理常见类型转换
        String strValue = value.toString();

        try {
            if (targetType == Integer.class || targetType == int.class) {
                return Integer.parseInt(strValue);
            } else if (targetType == Long.class || targetType == long.class) {
                return Long.parseLong(strValue);
            } else if (targetType == Double.class || targetType == double.class) {
                return Double.parseDouble(strValue);
            } else if (targetType == Float.class || targetType == float.class) {
                return Float.parseFloat(strValue);
            } else if (targetType == Boolean.class || targetType == boolean.class) {
                return Boolean.parseBoolean(strValue);
            } else if (targetType == String.class) {
                return strValue;
            }
            // 可以添加更多类型转换逻辑
        } catch (NumberFormatException e) {
            System.err.println("类型转换失败: " + value + " -> " + targetType.getName());
        }

        return value; // 无法转换时返回原值
    }

    /*private static Object convertType(Object value, Class<?> fieldTypeClass) {
        Object retVal;

        if (fieldTypeClass.isAssignableFrom(Long.class)
                || fieldTypeClass.isAssignableFrom(long.class)) {
            retVal = Long.parseLong(value.toString());
        } else if (fieldTypeClass.isAssignableFrom(Integer.class)
                || fieldTypeClass.isAssignableFrom(int.class)) {
            retVal = Integer.parseInt(value.toString());
        } else if (fieldTypeClass.isAssignableFrom(Float.class)
                || fieldTypeClass.isAssignableFrom(float.class)) {
            retVal = Float.parseFloat(value.toString());
        } else if (fieldTypeClass.isAssignableFrom(Double.class)
                || fieldTypeClass.isAssignableFrom(double.class)) {
            retVal = Double.parseDouble(value.toString());
        } else if (fieldTypeClass.isAssignableFrom(Boolean.class)
                || fieldTypeClass.isAssignableFrom(boolean.class)) {
            retVal = Boolean.valueOf(value.toString());
        } else {
            retVal = value;
        }
        return retVal;
    }*/
}
